<?
##########################################################################
#		DOCUMENTATION
##########################################################################
# Class that extends the core class. This module will provide the methods
# needed by the site to access categories' informations.
#
# © LiberLab group, 2011
##########################################################################

require_once("core.php");

class Category extends Core{
	public function __construct() {
		parent::__construct();
	}

	public function getCategoriesNum($orderBy = null, $desc = false, $categoryId = null, $limit = 20, $startId = 0, $fresh = false){
		# get the number of books in a category
		$database = self::$database;
		$cache = self::$cache;
		$query = "SELECT * FROM categoryNumBooks";
		$query = $this->orderByAddon($query, $orderBy, $desc);
		$query = $this->limitAddon($query, $limit, $startId);
		$cacheCheck = $this->cacheCheck($query, $fresh);
		if ($cacheCheck[0] != null){return $cacheCheck[0];}
		if ($categoryId){
			$query = $query . " WHERE id=:id";
			$stpdo = $database->getStpdo($query);
			$stpdo->bindParam(':categoryId', $categoryId, PDO::PARAM_STR); 
			$stpdo->execute(); 
		}else{
			$stpdo = $database->query($query);
		}
		$rows = $stpdo->fetchAll(PDO::FETCH_OBJ);
		if ($rows){
			$this->cacheInsert($rows, $cacheCheck[1]);
		}
		return $rows;
	}
	
	public function getBooks($full = false, $categoryOrder = true, $orderBy = null, $desc = false, $categoryId = null, 
											$startId = 0, $limit = 20, $fresh = false){
		# get all books with some options (i.e. category, ordered as you want and so on)
		$database = self::$database;
		if ($full){
			if ($limit and $database->sanitize(array($limit, $startId))){					
				$query = "SELECT * FROM booksAuthors ba JOIN (SELECT id, CONCAT(name, \" \", surname) as author FROM authors) a ON ba.authorId = a.id JOIN (SELECT * FROM booksFullInfos WHERE categoryId = :categoryId LIMIT $startId, $limit) b ON ba.bookId=b.bookId";
			}else{
				$query = "SELECT * FROM booksAuthors ba JOIN (SELECT id, CONCAT(name, \" \", surname) as author FROM authors) a ON ba.authorId = a.id JOIN (SELECT * FROM booksFullInfos WHERE categoryId = :categoryId) b ON ba.bookId=b.bookId";
			}
		}else{
			$query = "SELECT * FROM booksBasicInfos";
		}
		# if there's not a category id use the query command (faster)
		if (!$categoryId){
			$query = str_replace(" WHERE categoryId = :categoryId", "", $query);
			$query = $this->orderByAddon($query, $orderBy, $desc);
			$cacheCheck = $this->cacheCheck($query, $fresh);
			if ($cacheCheck[0] != null){return $cacheCheck[0];}
			$stpdo = $database->query($query);
		}else{
			$query = $this->orderByAddon($query, $orderBy, $desc);
			$cacheCheck = $this->cacheCheck($query, $fresh);
			if ($cacheCheck[0] != null){return $cacheCheck[0];}
			$stpdo = $database->getStpdo($query);
			$stpdo->bindParam(':categoryId', $categoryId, PDO::PARAM_STR); 
			$stpdo->execute(); 
		}

		$categories = array();
		$books = array();
		
		# divide each row to the category it belongs
		if ($categoryOrder){
			while($row = $stpdo->fetch(PDO::FETCH_OBJ)){
				$catId = $row->categoryId;
				$category = $row->category;
				$bookId = $row->bookId;
				# fix multiple authors
				if(isset($books[$bookId]) and $full){
					$categories[$catId]->books[$books[$bookId]]->authors = $categories[$catId]->books[$books[$bookId]]->authors . ", " . $row->author;
				}else{
					if ($full){
						if (isset($categories[$catId]->books)){
							$books[$bookId] = count($categories[$catId]->books);
						}else{
							$books[$bookId] = 0;
						}
						
						$row->authors = $row->author;
						unset($row->author);
					}
					$singleBook = $row;
					$row = new stdClass();
					if ($categoryId){
						$row->categoryId = $catId;
					}
					$row->category = $category;
					unset($singleBook->category);
					unset($singleBook->categoryId);
					# row = category data
					# singleBook = data of the single book
					# merging the array of the books already inserted with the new array
					if (isset($categories[$catId])){
						$categories[$catId]->books = array_merge($categories[$catId]->books, array($singleBook));
					}else{
						# create the whole new structure (first book for this category)
						$categories[$catId] = $row;
						$categories[$catId]->books = array(0 => $singleBook);
					}
				}
			}
			$this->cacheInsert($categories, $cacheCheck[1]);
			return $categories;
		}
		# the category order is not required, just merge the authors
		$rows = array();
		while($row = $stpdo->fetch(PDO::FETCH_OBJ)){
			if (isset($books[$row->bookId])){
				$rows[$books[$row->bookId]]->authors = $rows[$books[$row->bookId]]->authors . ", " . $row->author;
			}else{
				$row->authors = $row->author;
				unset($row->author);
				$books[$row->bookId] = count($rows);
				$rows[] = $row;
			}
		}
		return $rows;
	}	
	
	public function getCategories($categoryId = null, $full = false, $fresh = false){
		# extend the functionality of getBooks with the functionalities of getCategoriesNum
		$categoriesNumeric = $this->getCategoriesNum("books", true, $categoryId, $fresh);
		$categoriesBooks = $this->getBooks($full, true, "pubblicationData", true, $categoryId, null, 20, $fresh);
		# use mixedCategories to preserv the numBooks order
		$mixedCategories = array();
		foreach($categoriesNumeric as $category){
			$categoriesBooks[$category->id]->booksNum = $category->books;
			$mixedCategories[$category->id] = $categoriesBooks[$category->id];
		}
		return $mixedCategories;
	}

	public function __destruct() {
		parent::__destruct();
	}
};

#$c = new Category();
#print_r($c->getCategoriesNum("books", true));
?>
